var Settings;

(function () {
    var instance;

    Settings = function () {
        var subsTimeout, displayedVideos, pollingPeriod, sorting, ignore,
                removeWatched, thumbCyclePeriod, primarySort,
                enableNotifications, notificationTimeout, lastNotifiedVideo,
                lastNotifiedVideoTime, hideDonation, middleClickBehaviour;

        // Settings is a singleton class
        if (instance) {
            return instance;
        }
        instance = this;

        this.getSubsTimeout = function () {
            return subsTimeout;
        };

        this.setSubsTimeout = function (timeout) {
            subsTimeout = timeout;
            localStorage.setItem('subsTimeout', subsTimeout);
        };

        this.getDisplayedVideos = function () {
            return displayedVideos;
        };

        this.setDisplayedVideos = function (number) {
            displayedVideos = number;
            localStorage.setItem('displayedVideos', displayedVideos);
        };

        this.getPollingPeriod = function () {
            return pollingPeriod;
        };

        this.setPollingPeriod = function (period) {
            pollingPeriod = period;
            localStorage.setItem('pollingPeriod', pollingPeriod);
        };

        this.getSorting = function () {
            return sorting;
        };

        this.setSorting = function (newSorting) {
            sorting = newSorting;
            localStorage.setItem('sorting', sorting);
        };

        this.getIgnore = function () {
            return ignore;
        };

        this.setIgnore = function (newIgnore) {
            ignore = newIgnore;
            localStorage.setItem('ignore', ignore);
        };

        this.getRemoveWatched = function () {
            return removeWatched;
        };

        this.setRemoveWatched = function (newRemoveWatched) {
            removeWatched = newRemoveWatched;
            localStorage.setItem('removeWatched', removeWatched);
        };

        this.getThumbCyclePeriod = function () {
            return thumbCyclePeriod;
        };

        this.setThumbCyclePeriod = function (newThumbCyclePeriod) {
            thumbCyclePeriod = newThumbCyclePeriod;
            localStorage.setItem('thumbCyclePeriod', thumbCyclePeriod);
        };

        this.getPrimarySort = function () {
            return primarySort;
        };

        this.setPrimarySort = function (newPrimarySort) {
            primarySort = newPrimarySort;
            localStorage.setItem('primarySort', primarySort);
        };

        this.getEnableNotifications = function () {
            return enableNotifications;
        };

        this.setEnableNotifications = function (newEnableNotifications) {
            enableNotifications = newEnableNotifications;
            localStorage.setItem('enableNotifications', enableNotifications);
        };

        this.getNotificationTimeout = function () {
            return notificationTimeout;
        };

        this.setNotificationTimeout = function (newNotificationTimeout) {
            notificationTimeout = parseInt(newNotificationTimeout, 10);
            localStorage.setItem('notificationTimeout', notificationTimeout);
        };

        this.getLastNotifiedVideo = function () {
            return lastNotifiedVideo;
        };

        this.setLastNotifiedVideo = function (newLastNotifiedVideo) {
            lastNotifiedVideo = newLastNotifiedVideo;
            localStorage.setItem('lastNotifiedVideo', lastNotifiedVideo);
        };

        this.getLastNotifiedVideoTime = function () {
            return lastNotifiedVideoTime;
        };

        this.setLastNotifiedVideoTime = function (newLastNotifiedVideoTime) {
            lastNotifiedVideoTime = newLastNotifiedVideoTime;
            localStorage.setItem('lastNotifiedVideoTime',
                    lastNotifiedVideoTime);
        };

        /**
         * Returns the current settings for hiding the donation button in the
         * options page. The returned value is either '' or 'true'.
         *
         * @return The current settings for hiding the donation button.
         */
        this.getHideDonation = function () {
            return hideDonation;
        };

        /**
         * Sets the new settings for hiding the donation button in the options
         * page and store them in the persistent local storage.
         *
         * @param {String} newHideDonation New settings for hiding donation
         * button. Empty string '' represents false, 'true' represents true.
         * No other values should be used.
         */
        this.setHideDonation = function (newHideDonation) {
            hideDonation = newHideDonation;
            localStorage.setItem('hideDonation', hideDonation);
        };

        /**
         * Returns the currently set behaviour of the mouse middle click on the
         * the video list. Returned value can be '' for opening/updating
         * video tab in background or '1' for always opening a new tab.
         *
         * @return The current settings for the mouse middle click.
         */
        this.getMiddleClickBehaviour = function () {
            return middleClickBehaviour;
        };

        /**
         * Sets the new behaviour of the mouse middle button click on the video
         * list. The behaviour is specified as '' (empty string) for
         * opening/updating video tab in background or '1' for always opening a
         * new tab.
         *
         * @param {String} newBehaviour.
         */
        this.setMiddleClickBehaviour = function (newBehaviour) {
            middleClickBehaviour = newBehaviour;
            localStorage.setItem('middleClickBehaviour', middleClickBehaviour);
        };

        /**
         * Returns the time period after which the records of videos deleted
         * from the "new videos" list expire. The expired records should be
         * deleted automatically.
         *
         * <p>Note: This method currently always returns a value representing
         * the time period of ignored videos multiplied by 1.5 - or 0 if there
         * is no time limit for the ignored videos.</p>
         *
         * @returns The expiration delay for the deleted videos in seconds or 0
         *          if the deleted video entries are never to be removed.
         */
        this.getDeletedVideosExpiration = function () {
            return this.getIgnore() ? this.getIgnore() * 1.5 : 0;
        };

        /**
         * Reloads the extension's settings from the HTML5 local storage.
         */
        this.reload = function () {
            subsTimeout = parseInt(getItem("subsTimeout", "86400"), 10);
            displayedVideos = parseInt(getItem("displayedVideos", "5"), 10);
            pollingPeriod = parseInt(getItem("pollingPeriod", "900"), 10);
            sorting = getItem("sorting", "1");
            ignore = parseInt(getItem("ignore", "2419200"), 10);
            removeWatched = getItem("removeWatched", "1");
            thumbCyclePeriod = parseFloat(getItem("thumbCyclePeriod", "0.7"));
            primarySort = getItem("primarySort", "1");
            enableNotifications = getItem("enableNotifications", "1");
            notificationTimeout = parseInt(getItem("notificationTimeout", "5"),
                    10);
            lastNotifiedVideo = getItem("lastNotifiedVideo", "");
            lastNotifiedVideoTime = getItem("lastNotifiedVideoTime", "");
            hideDonation = getItem("hideDonation", "");
            middleClickBehaviour = getItem("middleClickBehaviour", "1");
        };

        // setup after instaling
        if (!localStorage.getItem('useOAuth')) {
            chrome.tabs.create({
                url: chrome.extension.getURL('install.html')
            });
        }

        this.reload();

        /**
         * Retrieve the specified item from the local storage or returns the
         * provided default value.
         * 
         * @param {string} item Name of the local storage item to retrieve.
         * @param {string} defaultValue
         * @returns {string}
         */
        function getItem(item, defaultValue) {
            var storedValue;
            storedValue = localStorage.getItem(item);
            if (storedValue === null) {
                return defaultValue;
            }
            return storedValue;
        }

        return instance;
    };
}());
